const macros: Array<() => void> = [],
  micros: Array<() => void> = [];

function run(tasks: Array<() => void>, callback?: () => void) {
  let func = tasks.shift();

  do {
    func?.();
    callback?.();
    func = tasks.shift();
  } while (func);
}

function runMicro() {
  run(micros);
}

function runMacro() {
  run(macros, runMicro);
}

function eventLoop() {
  runMicro();

  runMacro();

  requestIdleCallback(eventLoop);
}

function pushMacroTask(...tasks: Array<() => void>) {
  macros.push(...tasks);
}

function pushMicroTask(...tasks: Array<() => void>) {
  micros.push(...tasks);
}

requestIdleCallback(eventLoop);

export { pushMacroTask, pushMicroTask };
